import os
from flask import Blueprint, render_template, request, flash, redirect, url_for, current_app, jsonify, send_file
from werkzeug.utils import secure_filename
from app.models import Word, db, User, PointsRecord, Homework
from PIL import Image
import pytesseract
import re
from datetime import datetime
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import time
import hashlib
import uuid
import json
from urllib.parse import quote
import random
import csv
import pandas as pd
from io import BytesIO, StringIO

main = Blueprint('main', __name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'png', 'jpg', 'jpeg', 'gif'}

def extract_words_from_image(image_path):
    try:
        image = Image.open(image_path)
        text = pytesseract.image_to_string(image)
        words = re.findall(r'\b[a-zA-Z]+\b', text)
        return [word.lower() for word in words]
    except Exception as e:
        print(f"Error processing image: {e}")
        return []

def get_baidu_translation(word):
    """使用百度翻译API获取中文翻译"""
    try:
        # 百度翻译API配置
        appid = '20241206002221526'  # 替换为你的百度翻译API appid
        secret_key = 'fcqa7AzlESJD0dGcQtMB'  # 替换为你的百度翻译API secret key
        
        # 如果没有配置百度翻译API，使用离线词典
        COMMON_WORDS = {
            'hello': '你好',
            'world': '世界',
            'computer': '计算机',
            'book': '书',
            'student': '学生',
            # ... 可以添加更多常用词
        }
        
        # 先检查是否在常用词典中
        if word.lower() in COMMON_WORDS:
            return COMMON_WORDS[word.lower()]
            
        # 如果配置了百度翻译API，使用在线翻译
        if appid != 'your_appid' and secret_key != 'your_secret_key':
            salt = str(random.randint(32768, 65536))
            sign = appid + word + salt + secret_key
            sign = hashlib.md5(sign.encode()).hexdigest()
            
            url = 'http://api.fanyi.baidu.com/api/trans/vip/translate'
            params = {
                'q': word,
                'from': 'en',
                'to': 'zh',
                'appid': appid,
                'salt': salt,
                'sign': sign
            }
            
            response = requests.get(url, params=params)
            if response.status_code == 200:
                result = response.json()
                if 'trans_result' in result:
                    return result['trans_result'][0]['dst']
        
        # 果上述方法都失败，使用备用API
        url = f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}"
        response = requests.get(url)
        if response.status_code == 200:
            data = response.json()[0]
            translations = []
            for meaning in data.get('meanings', []):
                part_of_speech = meaning.get('partOfSpeech', '')
                for definition in meaning.get('definitions', []):
                    translations.append(f"{part_of_speech}. {definition.get('definition', '')}")
                    if len(translations) >= 3:  # 最多显示3个释义
                        break
            return '\n'.join(translations)
        
        return f"[{word}的翻译暂时不可用]"
        
    except Exception as e:
        print(f"Translation error for word '{word}': {e}")
        return f"[{word}的翻译暂时不可用]"

def get_word_details(word):
    """从外部API获取单词详情"""
    # 预设的常用单词例句
    EXAMPLE_SENTENCES = {
        'hello': 'Hello, nice to meet you!',
        'world': 'The world is becoming more connected.',
        'book': 'I borrowed a book from the library.',
        'computer': 'She uses her computer for work every day.',
        'student': 'He is a hardworking student.',
        'school': 'The school opens at 8 AM.',
        'teacher': 'Our teacher explains things very clearly.',
        'friend': 'Tom is my best friend.',
        'time': 'What time is it now?',
        'day': 'Have a nice day!',
        'work': 'I need to work late today.',
        'home': 'I will be home soon.',
    }
    
    try:
        session = requests.Session()
        retry_strategy = Retry(
            total=3,
            backoff_factor=1,
            status_forcelist=[500, 502, 503, 504]
        )
        adapter = HTTPAdapter(max_retries=retry_strategy)
        session.mount("http://", adapter)
        session.mount("https://", adapter)

        # 获取单词基本信息
        response = session.get(
            f'https://api.dictionaryapi.dev/api/v2/entries/en/{word}',
            timeout=10
        )

        if response.status_code == 200:
            data = response.json()[0]
            audio_url = next((phonetic['audio'] 
                            for phonetic in data.get('phonetics', [])
                            if phonetic.get('audio')), '')
            # 尝试从API获取例句
            example = ''
            for meaning in data.get('meanings', []):
                for definition in meaning.get('definitions', []):
                    if definition.get('example'):
                        example = definition['example']
                        break
                if example:
                    break
            
            # 如果API没有提供例句，使用预设例句或生成更有意义的例句
            if not example:
                if word.lower() in EXAMPLE_SENTENCES:
                    example = EXAMPLE_SENTENCES[word.lower()]
                else:
                    # 根据词性生成基本例句
                    pos = data.get('meanings', [{}])[0].get('partOfSpeech', '')
                    if pos == 'verb':
                        example = f"I {word} every day."
                    elif pos == 'noun':
                        example = f"This {word} is very important."
                    elif pos == 'adjective':
                        example = f"The weather is {word} today."
                    else:
                        example = f"We often use the word '{word}' in English."
            
            pronunciation = data.get('phonetic', '')
            
            # 获取中文翻译
            translation = get_baidu_translation(word)
            
            return {
                'audio_url': audio_url,
                'example': example,
                'pronunciation': pronunciation or f"/{word}/",
                'translation': translation
            }
    except Exception as e:
        print(f"Error fetching word details: {e}")
        # 发生错误时也使用预设例句
        example = EXAMPLE_SENTENCES.get(word.lower(), f"We use '{word}' in daily conversation.")
        return {
            'audio_url': '',
            'example': example,
            'pronunciation': f"/{word}/",
            'translation': f"[{word}的翻译暂时不可用]"
        }

@main.route('/', methods=['GET', 'POST'])
def index():
    user = User.get_or_create_default_user()
    ## 去除每日积分
    ## daily_points = user.check_daily_points()

    daily_points = {'points': 0, 'message': '欢迎回来'}
    
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file uploaded', 'error')
            return redirect(request.url)
            
        file = request.files['file']
        if file.filename == '':
            flash('No selected file', 'error')
            return redirect(request.url)
            
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            filepath = os.path.join(current_app.config['UPLOAD_FOLDER'], filename)
            file.save(filepath)
            
            words = extract_words_from_image(filepath)
            new_words_count = 0
            
            for word_text in words:
                existing_word = Word.query.filter_by(word=word_text.lower()).first()
                if not existing_word:
                    try:
                        details = get_word_details(word_text)
                        new_word = Word(
                            word=word_text.lower(),
                            pronunciation=details['pronunciation'],
                            audio_url=details['audio_url'],
                            example=details['example'],
                            translation=details['translation'],  # 添加翻译
                            next_review_date=datetime.utcnow()
                        )
                        db.session.add(new_word)
                        db.session.commit()
                        new_words_count += 1
                    except Exception as e:
                        print(f"Error adding word {word_text}: {e}")
                        db.session.rollback()
            
            flash(f'Successfully recognized {len(words)} words, added {new_words_count} new words!', 'success')
            
    words = Word.query.order_by(Word.word).all()
    daily_words = Word.get_daily_words()
    stats = Word.get_statistics()  # 获取统计数据
    
    # 获取最近的积分记录
    recent_points = PointsRecord.query.order_by(
        PointsRecord.created_at.desc()
    ).limit(5).all()
    
    # 获取作业列表
    homework_list = Homework.query.all()
    recent_homework = Homework.get_recent_homework()
    subject_times = Homework.get_total_study_time()
    
    return render_template('index.html', 
                         user=user,
                         words=words, 
                         daily_words=daily_words, 
                         stats=stats,
                         daily_points=daily_points,
                         recent_points=recent_points,
                         homework_list=homework_list,
                         recent_homework=recent_homework,
                         subject_times=subject_times)

@main.route('/review/<int:word_id>', methods=['POST'])
def review_word(word_id):
    word = Word.query.get_or_404(word_id)
    mastered = request.json.get('mastered', False)
    word.update_review_status(mastered)
    
    # 奖励复习积分
    points_data = word.award_points_for_review()
    
    return jsonify({
        'success': True,
        'points': points_data
    })

@main.route('/export/<format>')
def export_words(format):
    """导出单词库，支持 CSV 和 Excel 格式"""
    words = Word.query.order_by(Word.word).all()
    
    if format == 'csv':
        # 创建 CSV 内存文件
        si = StringIO()
        writer = csv.writer(si)
        
        # 写入表头
        writer.writerow(['单词', '音标', '翻译', '例句', '添加时间', '复习次数', '是否掌握'])
        
        # 写入数据
        for word in words:
            writer.writerow([
                word.word,
                word.pronunciation,
                word.translation,
                word.example,
                word.created_at.strftime('%Y-%m-%d'),
                word.review_count,
                '是' if word.mastered else '否'
            ])
        
        # 准备应
        output = BytesIO()
        output.write(si.getvalue().encode('utf-8-sig'))  # 使用 UTF-8-SIG 以支持中文
        output.seek(0)
        
        return send_file(
            output,
            mimetype='text/csv',
            as_attachment=True,
            download_name=f'vocabulary_{datetime.now().strftime("%Y%m%d")}.csv'
        )
        
    elif format == 'excel':
        # 创建 DataFrame
        data = {
            '单词': [],
            '音标': [],
            '翻译': [],
            '例句': [],
            '添加时间': [],
            '复习次数': [],
            '是否掌握': []
        }
        
        for word in words:
            data['单词'].append(word.word)
            data['音标'].append(word.pronunciation)
            data['翻译'].append(word.translation)
            data['例句'].append(word.example)
            data['添加时间'].append(word.created_at.strftime('%Y-%m-%d'))
            data['复习次数'].append(word.review_count)
            data['是否掌握'].append('是' if word.mastered else '否')
        
        df = pd.DataFrame(data)
        
        # 创建 Excel 内存文件
        output = BytesIO()
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='单词库', index=False)
            
            # 获取 workbook 和 worksheet 对象
            workbook = writer.book
            worksheet = writer.sheets['单词库']
            
            # 设置列宽
            worksheet.set_column('A:A', 15)  # 单词列
            worksheet.set_column('B:B', 15)  # 音标列
            worksheet.set_column('C:C', 30)  # 翻译列
            worksheet.set_column('D:D', 40)  # 例句列
            worksheet.set_column('E:G', 12)  # 其他列
        
        output.seek(0)
        
        return send_file(
            output,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            as_attachment=True,
            download_name=f'vocabulary_{datetime.now().strftime("%Y%m%d")}.xlsx'
        )
    
    else:
        return "Unsupported format", 400

@main.context_processor
def inject_user():
    """注入用户对象到所有模板"""
    return {'user': User.get_or_create_default_user()}

@main.route('/homework', methods=['GET', 'POST'])
def homework():
    if request.method == 'POST':
        # 添加请求头检查，防止重复提交
        if request.headers.get('X-Requested-With') != 'XMLHttpRequest':
            return jsonify({'success': False, 'message': '无效的请求'})
            
        # 处理作业提交
        subject = request.form.get('subject')
        content = request.form.get('content')
        hours = int(request.form.get('hours', 0))
        minutes = int(request.form.get('minutes', 0))
        
        # 计算总分钟数
        total_minutes = hours * 60 + minutes
        
        # 创建新的作业记录
        new_homework = Homework(
            subject=subject,
            content=content,
            hours=hours,
            minutes=minutes,
            total_minutes=total_minutes
        )
        
        db.session.add(new_homework)
        db.session.commit()
        
        # 添加积分奖励
        user = User.get_or_create_default_user()
        points_earned = min(total_minutes // 30, 4)  # 每30分钟1分，最多4分
        points_earned = max(points_earned, 1) # 最少1积分
        user.add_points(points_earned)
        
        # 记录积分获得
        points_record = PointsRecord(
            user_id=user.id,
            points=points_earned,
            reason=f'完成{subject}作业，学习{total_minutes}分钟'
        )
        db.session.add(points_record)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'points_earned': points_earned
        })
    
    # GET 请求：获取作业记录
    recent_homework = Homework.get_recent_homework()
    subject_times = Homework.get_total_study_time()
    
    return render_template('homework.html', 
                         recent_homework=recent_homework,
                         subject_times=subject_times)

@main.route('/add_word', methods=['GET', 'POST'])
def add_word():
    if request.method == 'POST':
        word_text = request.form.get('word')
        user_example = request.form.get('example', '').strip()
        existing_word = Word.query.filter_by(word=word_text.lower()).first()
        if not existing_word:
            details = get_word_details(word_text)
            # 如果用户提供了例句，使用用户的例句
            example = user_example if user_example else details['example']
            new_word = Word(
                word=word_text.lower(),
                pronunciation=details['pronunciation'],
                audio_url=details['audio_url'],
                example=example,
                translation=details['translation'],
                next_review_date=datetime.utcnow()
            )
            db.session.add(new_word)
            db.session.commit()
            # 添加成功后设置闪现消息
            return jsonify({'success': True, 'message': '单词添加成功！'})
        else:
            return jsonify({'success': False, 'message': '单词已经存在'})
    
    return render_template('add_word.html')

@main.route('/init_database')
def init_database():
    try:
        # 检查是否已存在单词
        if Word.query.count() == 0:
            # 只在没有单词时添加示例单词
            sample_words = [
                {
                    'word': 'hello',
                    'pronunciation': '/həˈləʊ/',
                    'translation': '你好',
                    'example': 'Hello, how are you?',
                    'audio_url': 'https://api.dictionaryapi.dev/media/pronunciations/en/hello-uk.mp3'
                },
                {
                    'word': 'world',
                    'pronunciation': '/wɜːld/',
                    'translation': '世界',
                    'example': 'Hello, world!',
                    'audio_url': 'https://api.dictionaryapi.dev/media/pronunciations/en/world-uk.mp3'
                }
            ]
            
            for word_data in sample_words:
                word = Word(
                    word=word_data['word'],
                    pronunciation=word_data['pronunciation'],
                    translation=word_data['translation'],
                    example=word_data['example'],
                    audio_url=word_data['audio_url'],
                    next_review_date=datetime.utcnow()
                )
                db.session.add(word)
            
            flash('已添加示例词！', 'success')
        else:
            flash('单词库已存在，跳过初始化。', 'info')

        # 检查是否已存在作业记录
        if Homework.query.count() == 0:
            # 只在没有作业记录时添加示例作业
            homework = Homework(
                subject='英语',
                content='完成单词复习',
                hours=1,
                minutes=30,
                total_minutes=90
            )
            db.session.add(homework)
            flash('已添加示例作业！', 'success')
        else:
            flash('作业记录已存在，跳过初始化。', 'info')

        db.session.commit()
    except Exception as e:
        db.session.rollback()
        flash(f'初始化数据库失败：{str(e)}', 'error')

    return redirect(url_for('main.index'))

@main.route('/get_homework_list')
def get_homework_list():
    recent_homework = Homework.get_recent_homework()
    subject_times = Homework.get_total_study_time()
    return jsonify({
        'recent_homework': [
            {
                'subject': hw.subject,
                'content': hw.content,
                'hours': hw.hours,
                'minutes': hw.minutes,
                'created_at': hw.created_at.strftime('%Y-%m-%d %H:%M')
            } for hw in recent_homework
        ],
        'subject_times': subject_times
    })

@main.route('/add_points', methods=['POST'])
def add_points():
    try:
        points = int(request.form.get('points', 0))
        reason = request.form.get('reason', '手动添加积分')
        
        if points <= 0:
            return jsonify({
                'success': False,
                'message': '积分必须大于0'
            })
        
        user = User.get_or_create_default_user()
        user.add_points(points)
        
        # 记录积分获得
        points_record = PointsRecord(
            user_id=user.id,
            points=points,
            reason=reason
        )
        db.session.add(points_record)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': f'成功添加 {points} 积分',
            'points': points
        })
    except ValueError:
        return jsonify({
            'success': False,
            'message': '请输入有效的积分数值'
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'添加积分失败：{str(e)}'
        })

@main.route('/newyear2025')
def newyear2025():
    return render_template('newyear2025.html')

@main.route('/reset_points', methods=['POST'])
def reset_points():
    try:
        # 重置所有用户的积分为0
        User.query.update({User.points: 0})
        db.session.commit()
        return jsonify({'status': 'success', 'message': '积分已重置'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'status': 'error', 'message': str(e)}), 500